package cgl.narada.mgmt.common;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

/**
 * A command line arguments parser !<br>
 * Useful for storing key=value pairs which can be passed as command line
 * arguments to programs<br>
 * E.g. <code>runService --type=X --param=Y --exitOnError</code><br>
 * Here the various parameters are<br>
 * <li>service type (--type) = X</li>
 * <li>some parameter (--param) = Y</li>
 * <li>some boolean parameter set to true (--exitOnError)</li>
 *
 * Created on Jan 20, 2007<br>
 *
 * @author Harshawardhan Gadgil (hgadgil@grids.ucs.indiana.edu)
 */

public final class CommandlineArguments {

   static Logger log = Logger.getLogger("CommandlineArguments");
   private Hashtable <String, String> values = new Hashtable <String, String>();

   public CommandlineArguments() {
      // Constructs an empty arguments table
   }

   public CommandlineArguments(String[] args) {

      for (int i = 0; i < args.length; i++) {
         parseAndAddArg(args[i]);
      }
   }

   public CommandlineArguments(String argsLine) {
      StringTokenizer st = new StringTokenizer(argsLine, " ");
      while (st.hasMoreTokens()) {
         parseAndAddArg(st.nextToken());
      }
   }

   private void parseAndAddArg(String arg) {
      // Each argument is of the form
      // --key=value

      if (!arg.startsWith("--")) {
         log.warn("Error parsing argument: {" + arg + "}");
      } else {
         String key, value;
         int equalLoc = arg.indexOf("=");
         if (equalLoc == -1) {
            equalLoc = arg.length();
            value = "true";
         } else
            value = arg.substring(equalLoc + 1);

         key = arg.substring(2, equalLoc);

         values.put(key, value);
      }

   }

   public String[] toArgs() {
      ArrayList list = new ArrayList();
      for (Enumeration e = values.keys(); e.hasMoreElements();) {
         String key = (String) e.nextElement();
         String argument = "--" + key + "=" + values.get(key);
         list.add(argument);
      }

      return (String[]) list.toArray(new String[list.size()]);
   }

   public String toString() {
      StringBuffer buf = new StringBuffer();
      for (Enumeration e = values.keys(); e.hasMoreElements();) {
         String key = (String) e.nextElement();
         String argument = " --" + key + "=" + values.get(key);
         buf.append(argument);
      }

      return buf.toString();
   }

   public void setArgument(String key, String value) {
      if (value == null) {
         value = "true";
      }
      values.put(key, value);
   }

   public String getStringProperty(String key, String defaultValue) {
      String value = (String) values.get(key);
      return (value == null) ? defaultValue : value;
   }

   public int getIntProperty(String key, int defaultValue) {
      String value = (String) values.get(key);
      return (value == null) ? defaultValue : Integer.parseInt(value);
   }

   public boolean getBooleanProperty(String key, boolean defaultValue) {
      String value = (String) values.get(key);
      return (value == null) ? defaultValue : Boolean.valueOf(value)
               .booleanValue();
   }

   /**
    * Testing purposes only
    *
    * @param args
    */
   public static void main(String[] a) {

      String[] args = { "--key11=value1", "--key21=55", "--key31", };
      CommandlineArguments arg = new CommandlineArguments(args);

      System.out
               .println("Key11 = " + arg.getStringProperty("key11", "default"));
      System.out
               .println("Key12 = " + arg.getStringProperty("key12", "default"));
      System.out.println("Key21 = " + arg.getIntProperty("key21", 100));
      System.out.println("Key22 = " + arg.getIntProperty("key22", 100));
      System.out.println("Key31 = " + arg.getBooleanProperty("key31", false));
      System.out.println("Key32 = " + arg.getBooleanProperty("key32", false));

      arg.setArgument("regKey", "");

      System.out.println("Arguments: " + arg.toString());

      System.out.println("regKey = " + arg.getStringProperty("regKey", ""));
   }
}
